home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1997 October / pcx14_9710.iso / swag / textedit.swg / 0014_Simple editor for ascii text files.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-11-29  |  8.9 KB  |  375 lines

  1.  
  2. {
  3.  This is a very simple editor for ascii text files. It uses an array of
  4.  pointers and dynamic memory allocation for every line, so that lines can
  5.  easily be inserted or deleted without moving huge amounts of data.
  6.  There is no saving available, but this should be easy to include.
  7.  
  8.  I recommend compiling this as a protected mode application (far more
  9.  memory available), but you can also use it in real mode, if you want.
  10.  You can edit texts of every size (no 64K limit), they just have to fit
  11.  into your memory.
  12.  
  13.  This is Public Domain, feel free to use it for whatever you like, but at
  14.  your own risk !
  15.  
  16.  Any questions, comments, etc. : heiner@rummelplatz.uni-mannheim.de
  17.                                  Alexander Heiner
  18. }
  19.  
  20. uses crt,dos;
  21. {$F+}
  22.  
  23. type
  24.     D_LStr = record
  25.         StrLen: word;
  26.         Str: array[0..16383] of byte;
  27.     end;
  28.     P_LStr = ^D_Lstr;
  29.  
  30.     D_TmpStr=array[0..16383] of char;
  31.  
  32. var
  33.     LStr: array[0..16000] of P_LStr;
  34.     TmpStr: ^D_TmpStr;
  35.     YscrlPos,XscrlPos:longint;
  36.     CrX,CrY:word;
  37.     MaxLines:longint;
  38.     ch:char;
  39.     FName:string;
  40.  
  41. procedure OutString(x,y:word;s:string;tcol,bcol:byte);
  42. var p:pointer;
  43. begin
  44.      p:=@s;
  45.      asm
  46.         push    ds
  47.         mov     ax,SegB800
  48.         lds     si,p
  49.         mov     es,ax
  50.         imul    di,y,160
  51.         mov     ax,x
  52.         shr     ax,1
  53.         add     di,ax
  54.         mov     ah,bcol
  55.         shl     ah,4
  56.         add     ah,tcol
  57.         mov     cl,ds:[si]
  58.         inc     si
  59. @l1:
  60.         lodsb
  61.         stosw
  62.         dec     cl
  63.         jnz     @l1
  64.  
  65.         pop     ds
  66.      end;
  67. end;
  68.  
  69. procedure LoadText(Fname:string);
  70. var f:text;a,b:word;s:string;gmem:longint;
  71. begin
  72.      getmem(tmpStr,16384);
  73.      assign(f,Fname);
  74.      reset(f);
  75.      a:=0;gmem:=0;
  76.      while not eof(f) do begin
  77.            readln(f,TmpStr^);
  78.            b:=0;while TmpStr^[b]<>#0 do inc(b);
  79.  
  80.            if memavail>=2+b then begin
  81.               getmem(LStr[a],2+b);
  82.               move(TmpStr^,LStr[a]^.Str,b);
  83.               Lstr[a]^.StrLen:=b;
  84.               inc(gmem,b+2);
  85.            end else begin outstring(0,3,'Not enough memory.',7,0);halt(1);end;
  86.  
  87.            inc(a);if a>16000 then begin
  88.            outstring(0,3,'Line overflow (max.16000)',7,0);halt(1);end;
  89.  
  90.            str(a,s);outstring(0,0,'lines loaded: '+s,7,0);
  91.            str(gmem,s);outstring(0,1,'memory allocated: '+s+ ' bytes',7,0);
  92.      end;
  93.      MaxLines:=a-1;
  94.      freemem(tmpStr,16384);
  95. end;
  96.  
  97. procedure ShowAllText;
  98. var x,y,len:word;s:string;
  99. begin
  100.      for y:=0 to 23 do begin
  101.       s:='';
  102.       if LStr[y+Yscrlpos]<>NIL then begin
  103.          len:=LStr[y+Yscrlpos]^.StrLen;
  104.         if len>XscrlPos then begin
  105.          dec(len,XScrlPos);
  106.          if len>80 then len:=80;
  107.          move(LStr[y+Yscrlpos]^.Str[XScrlPos],s[1],len);
  108.          s[0]:=chr(len);
  109.         end;
  110.       end;
  111.       while s[0]<#80 do s:=s+' ';
  112.       OutString(0,y,s,11,0);
  113.      end;
  114. end;
  115.  
  116. procedure ScrollDown;
  117. begin
  118.      if YScrlPos>=(MAxLines-23) then exit;
  119.      inc(YScrlPos);
  120.      ShowAllText;
  121. end;
  122.  
  123. procedure ScrollUp;
  124. begin
  125.      if YScrlPos<1 then exit;
  126.      dec(YScrlPos);
  127.      ShowAllText;
  128. end;
  129.  
  130. procedure ScrollRight;
  131. begin
  132.      inc(XScrlPos);
  133.      ShowAllText;
  134. end;
  135.  
  136. procedure ScrollLeft;
  137. begin
  138.      if XScrlPos<1 then exit;
  139.      dec(XScrlPos);
  140.      ShowAllText;
  141. end;
  142.  
  143. procedure InsertChar(ch:char);
  144. var l1,add:word;
  145. begin
  146.      inc(CrX,XScrlPos);
  147.      l1:=LStr[CrY+YscrlPos]^.StrLen;
  148.      if (CrX+1)<=l1 then add:=1 else add:=(crx+1)-l1;
  149.  
  150.      getmem(TmpStr,l1+add);
  151.      move(LStr[CrY+YscrlPos]^.Str,TmpStr^,l1);
  152.      if (CrX+1)<=l1 then move(TmpStr^[CrX],TmpStr^[CrX+1],l1-crx) else
  153.      fillchar(TmpStr^[l1],crx-l1,32);
  154.      TmpStr^[Crx]:=ch;
  155.  
  156.      freemem(LStr[CrY+YscrlPos],2+l1);
  157.      getmem(LStr[CrY+YscrlPos],2+l1+add);
  158.  
  159.      move(TmpStr^,LStr[CrY+YscrlPos]^.Str,l1+add);
  160.      LStr[CrY+YscrlPos]^.StrLen:=l1+add;
  161.  
  162.      freemem(TmpStr,l1+add);
  163.      dec(CrX,XScrlPos);
  164.  
  165.      if CrX=79 then ScrollRight else inc(CrX);
  166.      ShowAllText;
  167.      gotoxy(CrX+1,CrY+1);
  168. end;
  169.  
  170. procedure DeleteLine(Lpos:byte);
  171. var y,l1,l2:word;
  172. begin
  173.      l1:=LStr[Lpos-1]^.StrLen;
  174.      l2:=LStr[Lpos]^.StrLen+l1;
  175.      getmem(TmpStr,l2);
  176.  
  177.      move(LStr[Lpos-1]^.Str,TmpStr^,l1);
  178.      move(LStr[Lpos]^.Str,TmpStr^[l1],Lstr[Lpos]^.StrLen);
  179.      freemem(LStr[Lpos-1],l1+2);
  180.      getmem(LStr[Lpos-1],l2+2);
  181.      move(TmpStr^,LStr[Lpos-1]^.Str,l2);
  182.      LStr[Lpos-1]^.StrLen:=l2;
  183.  
  184.      dec(MaxLines);
  185.      freemem(Lstr[Lpos],LStr[Lpos]^.StrLen+2);
  186.      for y:=Lpos to MaxLines do LStr[y]:=Lstr[y+1];
  187.      LStr[MaxLines+1]:=NIL;
  188.      freemem(TmpStr,l2);
  189.  
  190.      if CrY=0 then ScrollUp else begin dec(CrY);ShowAllText;end;
  191.      Crx:=l1;
  192.      gotoxy(CrX+1,CrY+1);
  193. end;
  194.  
  195. procedure DeleteChar;
  196. var l1:word;
  197. begin
  198.      inc(CrX,XScrlPos);
  199.      if Crx=0 then begin
  200.         DeleteLine(Cry+YscrlPos);
  201.         exit;
  202.      end;
  203.      l1:=LStr[CrY+YscrlPos]^.StrLen;
  204.  
  205.      getmem(TmpStr,l1);
  206.      move(LStr[CrY+YscrlPos]^.Str,TmpStr^,l1);
  207.      move(TmpStr^[CrX],TmpStr^[CrX-1],l1-crx);
  208.  
  209.      freemem(LStr[CrY+YscrlPos],2+l1);
  210.      getmem(LStr[CrY+YscrlPos],2+l1-1);
  211.  
  212.      move(TmpStr^,LStr[CrY+YscrlPos]^.Str,l1-1);
  213.      LStr[CrY+YscrlPos]^.StrLen:=l1-1;
  214.  
  215.      freemem(TmpStr,l1);
  216.      dec(CrX,XScrlPos);
  217.  
  218.      if CrX=0 then ScrollLeft else dec(CrX);
  219.      ShowAllText;
  220.      gotoxy(CrX+1,CrY+1);
  221. end;
  222.  
  223. procedure InsertLine;
  224. var y,l1:word;
  225. begin
  226.      inc(CrX,XScrlPos);
  227.      inc(MaxLines);
  228.      l1:=LStr[YscrlPos+CrY]^.StrLen;
  229.      for y:=MaxLines-1 downto Yscrlpos+CrY+1 do LStr[y+1]:=Lstr[y];
  230.  
  231.      if (CrX>=l1)or(l1=0) then begin
  232.         getmem(LStr[YscrlPos+CrY+1],2+1);
  233.         LStr[YscrlPos+CrY+1]^.StrLen:=0;
  234.      end else begin
  235.         getmem(LStr[YscrlPos+CrY+1],2+(l1-crx));
  236.         move(LStr[YscrlPos+CrY]^.Str[CrX],LStr[YscrlPos+CrY+1]^.Str,l1-crx);
  237.         LStr[YscrlPos+CrY+1]^.StrLen:=l1-crx;
  238.  
  239.         getmem(TmpStr,crx+1);
  240.         move(LStr[YscrlPos+CrY]^.Str,TmpStr^,crx);
  241.         freemem(LStr[YscrlPos+CrY],2+l1);
  242.         getmem(LStr[YscrlPos+CrY],2+crx);
  243.         move(TmpStr^,LStr[YscrlPos+CrY]^.Str,crx);
  244.         LStr[YscrlPos+CrY]^.StrLen:=crx;
  245.         freemem(TmpStr,crx+1);
  246.      end;
  247.      dec(CrX,XScrlPos);
  248.  
  249.      XScrlPos:=0;
  250.      ShowAllText;
  251.      CrX:=0;
  252.      if CrY=23 then ScrollDown else inc(CrY);
  253.      gotoxy(CrX+1,CrY+1);
  254. end;
  255.  
  256.  
  257. {----- cursor control ------------------------------------------------------}
  258.  
  259. procedure CursorDown;
  260. begin
  261.      if Cry+YscrlPos>=MAxLines then exit;
  262.      if CrY=23 then ScrollDown else inc(CrY);
  263.      gotoxy(CrX+1,CrY+1);
  264. end;
  265.  
  266. procedure CursorUp;
  267. begin
  268.      if CrY=0 then ScrollUp else dec(CrY);
  269.      gotoxy(CrX+1,CrY+1);
  270. end;
  271.  
  272. procedure CursorRight;
  273. begin
  274.      if CrX=79 then ScrollRight else inc(CrX);
  275.      gotoxy(CrX+1,CrY+1);
  276. end;
  277.  
  278. procedure CursorLeft;
  279. begin
  280.      if CrX=0 then ScrollLeft else dec(CrX);
  281.      gotoxy(CrX+1,CrY+1);
  282. end;
  283.  
  284. procedure CursorAtLineEnd;
  285. begin
  286.      CrX:=LStr[YscrlPos+CrY]^.StrLen;
  287.      if CrX>79 then begin XScrlPos:=CrX-79;CrX:=79; end else begin
  288.        if CrX>XScrlPos then dec(CrX,XScrlPos) else XScrlPos:=0;
  289.      end;
  290.      gotoxy(CrX+1,CrY+1);
  291.      ShowAllText;
  292. end;
  293.  
  294. procedure CursorAtLineStart;
  295. begin
  296.      XScrlPos:=0;
  297.      CrX:=0;
  298.      gotoxy(1,CrY+1);
  299.      ShowAllText;
  300. end;
  301.  
  302. procedure PageDown;
  303. begin
  304.      inc(YscrlPos,22);if yscrlpos>MaxLines-23 then Yscrlpos:=Maxlines-23;
  305.      ShowAllText;
  306. end;
  307.  
  308. procedure PageUp;
  309. begin
  310.      dec(YscrlPos,22);if yscrlpos<0 then Yscrlpos:=0;
  311.      ShowAllText;
  312. end;
  313.  
  314.  
  315. {----- status line ---------------------------------------------------------}
  316.  
  317. procedure ShowStats;
  318. var s,s2,s3:string;
  319. begin
  320.      str(CrY+YScrlPos+1,s);
  321.      str(MaxLines+1,s2);
  322.      s3:='  '+FName;
  323.      if s3[0]>#40 then s3[0]:=#40;
  324.      while s3[0]<#40 do s3:=s3+' ';
  325.  
  326.      s3:=s3+'Line: '+s+' / '+s2+'     Row: ';
  327.      str(CrX+XScrlPos+1,s);
  328.      str(LStr[YscrlPos+CrY]^.StrLen,s2);
  329.      s3:=s3+s+' / '+s2;
  330.      while s3[0]<#80 do s3:=s3+' ';
  331.  
  332.      OutString(0,24,s3,0,7);
  333. end;
  334.  
  335.  
  336. {----- main ----------------------------------------------------------------}
  337.  
  338. begin
  339.  
  340.      FName:='test.doc';
  341.  
  342.      clrscr;
  343.      XscrlPos:=0;YscrlPos:=0;CrX:=0;CrY:=0;
  344.  
  345.      LoadText(FName);
  346.      ShowAllText;
  347.      ShowStats;
  348.      gotoxy(1,1);
  349.  
  350. repeat
  351.       repeat until keypressed;
  352.       ch:=readkey;
  353.       if ch=#0 then begin
  354.          ch:=readkey;
  355.          if ch=#80 then CursorDown;
  356.          if ch=#72 then CursorUp;
  357.          if ch=#77 then CursorRight;
  358.          if ch=#75 then CursorLeft;
  359.          if ch=#71 then CursorAtLineStart;
  360.          if ch=#79 then CursorAtLineEnd;
  361.          if ch=#81 then PageDown;
  362.          if ch=#73 then PageUp;
  363.          ShowStats;
  364.       end else begin
  365.         if ch<>#27 then
  366.          if ch=#8 then DeleteChar else
  367.           if ch=#13 then InsertLine else
  368.             InsertChar(ch);
  369.             ShowStats;
  370.       end;
  371. until ch=#27;
  372. end.
  373.  
  374.  
  375.